﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using Red.Controls.Depot.FileViewItemsProviders;
using Red.Controls.ViewModels;
using Red.Core;
using Red.Core.Containers;

namespace Red.Controls.Depot.ViewModels
{
    public class DepotTreeItemChangelistRoot : DepotTreeItem
    {
        #region Data

        public static readonly string ROOTNAME = "[cl]";
        public static readonly string ROOTPATH = $"{{{ROOTNAME},icon:appbar_location_circle}}";

        private List<PendingChangelistInfo> _changelists = new List<PendingChangelistInfo>();
        private static readonly Canvas _clIcon;

        #endregion Data

        #region Properties

        public Core.SourceControl.Monitor Monitor { get; private set; } = new Core.SourceControl.Monitor();

        #endregion Properties

        #region C-tor

        public DepotTreeItemChangelistRoot( DepotTreeItem parent, DepotInfo depot )
            : base( "Changelists", "List of user changelists", _clIcon, parent, depot )
        {
            Monitor.SourceControl = depot.SourceControl;

            //Need a way to unregister these events when this viewmodel is no longer required
            Monitor.ChangelistAdded += RebuildOnChangelistEvent;
            Monitor.ChangelistDeleted += RebuildOnChangelistEvent;
        }

        static DepotTreeItemChangelistRoot()
        {
            _clIcon = (Canvas)Application.Current.FindResource( "appbar_location_circle" );
        }
        
        #endregion C-tor
        
        #region Properties

        public override FileViewItemsProvider GetItemsProvider()
        {
            return new EmptyItemsProvider();
        }

        public override string BreadcrumbPath
        {
            get { return ROOTPATH; }
        }

        public override string PathElement
        {
            get { return ROOTNAME; }
        }

        public IEnumerable<PendingChangelistInfo> Changelists
        {
            get
            {
                return _changelists;
            }
        }

        #endregion Properties

        #region Implementation

        public override bool AcceptsDraggedData( IDataObject obj )
        {
            return obj.GetDataPresent( "Red.DepotDirectory" )
                || obj.GetDataPresent( "Red.DepotFile" );
        }

        public override void DropDraggedData( IDataObject obj )
        {
            Debug.Assert( AcceptsDraggedData( obj ) );

            if ( obj.GetDataPresent( "Red.DepotDirectory" ) )
            {
                var path = obj.GetData( "Red.DepotDirectory" ) as string;
                // TODO
            }
            else
            {
                var path = obj.GetData( "Red.DepotFile" ) as string;
                // TODO:
            }

            // TODO: Create a NEW CL item and add to it _changelists
        }

        #endregion Implementation

        #region LazyHierarchicalItem implementation

        protected override Task EnumerateChildrenAsync( IRangedCollection<DataItem> children )
        {
            children.Clear();

            _changelists = _depot.SourceControl.GetChangelists().Select( item => new PendingChangelistInfo { Description = item.Description, Id = item.Id } ).ToList();
            children.Add( new DepotTreeItemChangelist( new DefaultChangelistInfo(), this, _depot ) );
            foreach ( var clInfo in _changelists )
            {
                children.Add( new DepotTreeItemChangelist( clInfo, this, _depot ) );
            }

            return Task.CompletedTask;
        }

        #endregion LazyHierarchicalItem implementation

        #region Event Handlers


        private async void RebuildOnChangelistEvent( int changelistId )
        {
            await RebuildAsync();
        }

        #endregion Event Handlers
    }

    public class DepotTreeItemChangelist : DepotTreeItem
    {
        #region Data

        private static readonly Canvas _clIcon;
        private readonly PendingChangelistInfo _info;

        #endregion Data

        #region Properties

        public override FileViewItemsProvider GetItemsProvider()
        {
            return new ChangelistItemsProvider( _info.Id, Path, _depot );
        }

        public override string BreadcrumbPath
        {
            get { return ( $"{DepotTreeItemChangelistRoot.ROOTPATH}\\{ChangelistTitle}" ); }
        }

        public override IEnumerable<RedMenuDataItem> Menu
        {
            get
            {
                List<RedMenuDataItem> menu = new List<RedMenuDataItem>();
                menu.Add( new RedMenuDataItem( new CommandWrapper( DepotBrowserCommands.Submit, this ) ) );
                menu.Add( new RedMenuDataItem( new CommandWrapper( DepotBrowserCommands.EditChangelist, this ) ) );
                menu.Add( new RedMenuDataItem( new CommandWrapper( DepotBrowserCommands.DeleteChangelist, this ) ) );
                return menu;
            }
        }

        public int ChangelistId
        {
            get { return _info.Id; }
        }

        public string ChangelistTitle
        {
            get
            {
                if ( ChangelistId == -1 )
                {
                    return "Default";
                }

                return ChangelistId.ToString();
            }
        }

        public override string ShortName
        {
            get { return $"CL {ChangelistTitle}"; }
        }

        public override bool IsExpandable
        {
            get { return false; }
        }

        #endregion Properties

        #region C-tor

        public DepotTreeItemChangelist( PendingChangelistInfo info, DepotTreeItem parent, DepotInfo depot )
            : base( info.ToString(), info.Description, _clIcon, parent, depot )
        {
            _info = info;
        }

        static DepotTreeItemChangelist()
        {
            _clIcon = (Canvas)Application.Current.FindResource( "appbar_location_circle" );
        }
        
        #endregion C-tor

        #region LazyHierarchicalItem implementation

        public override bool AcceptsDraggedData( IDataObject obj )
        {
            return obj.GetDataPresent( "Red.DepotDirectory" )
                || obj.GetDataPresent( "Red.DepotFile" );
        }

        public override void DropDraggedData( IDataObject obj )
        {
            Debug.Assert( AcceptsDraggedData( obj ) );

            if ( obj.GetDataPresent( "Red.DepotDirectory" ) )
            {
                var path = obj.GetData( "Red.DepotDirectory" ) as string;
                // TODO
            }
            else
            {
                var path = obj.GetData( "Red.DepotFile" ) as string;
                // TODO:
            }

            // TODO: Add a CL to THIS _changelists
        }

        #endregion LazyHierarchicalItem implementation

        #region Public methods

        public bool CanSubmit()
        {
            return !( _info is DefaultChangelistInfo );
        }

        #endregion Public methods
    }
}